#include "link_list.h"
#include "error.h"
#include <stdio.h>
#include <stdlib.h>

/// @brief 新建链表
///@param freeEleFunc 释放元素内存函数
///@param printEleFunc 打印元素函数
/// @return
LinkList *newLinkList(FreeEleFunc *freeEleFunc, PrintEleFunc *printEleFunc) {
  LinkList *list = (LinkList *)malloc(sizeof(LinkList));
  checkError();
  list->size = 0;
  list->head = NULL;
  list->tail = NULL;
  list->freeEleFunc = freeEleFunc;
  list->printEleFunc = printEleFunc;
  return list;
}
/// @brief 打印链表中的元素
/// @param link_list
void printLinkList(LinkList *link_list) {
  printf_s("链表内容如下:\n");
  Node *temp = link_list->head;
  while (temp) {
    link_list->printEleFunc(temp->ele);
    temp = temp->next;
  }
}

/// @brief 清空链表
/// @param link_list
void clearLinkList(LinkList *link_list) {
  printf_s("清空链表\n");
  Node *temp = link_list->head;
  Node *next;
  while (temp) {
    next = temp->next;
    linkListFreeNode(link_list, temp);
    temp = next;
  }
  link_list->head = NULL;
  link_list->tail = NULL;
  link_list->size = 0;
}

/// @brief 添加元素
/// @param link_list
/// @param ele
void insertLinkListEle(LinkList *link_list, void *ele) {
  Node *node = (Node *)malloc(sizeof(Node));
  node->ele = ele;
  node->next = NULL;
  node->pre = NULL;
  if (link_list->tail == NULL) {
    link_list->head = link_list->tail = node;
  } else {
    node->pre = link_list->tail;
    link_list->tail->next = node;
    link_list->tail = node;
  }
  link_list->size++;
}

/// @brief 删除节点
/// @param link_list
/// @param id
/// @param getEleIdFunc  获取元素id的函数
void deleteLinkListNode(LinkList *link_list, int id,
                        GetEleIdFunc *getEleIdFunc) {
  Node *node = link_list->head;
  int eleId;
  while (node) {
    eleId = getEleIdFunc(node->ele);
    if (eleId != id) {
      node = node->next;
      continue;
    }
    Node *pre = node->pre;
    Node *next = node->next;
    linkListFreeNode(link_list, node);
    if (pre != NULL) {
      pre->next = next;
    } else {
      link_list->head = next;
    }

    if (next != NULL) {
      next->pre = pre;
    } else {
      link_list->tail = pre;
    }
    link_list->size--;
    break;
  }
  printf_s("删除学生:%d成功\n", id);
}

/// @brief 释放节点空间
/// @param node
void linkListFreeNode(LinkList *link_list, Node *node) {
  link_list->freeEleFunc(node->ele);
  free(node);
}

/// @brief 释放链表空间
/// @param link_list
void freeLinkList(LinkList *link_list) {
  if (link_list == NULL) {
    return;
  }
  clearLinkList(link_list);
  free(link_list);
  printf_s("释放LinkList\n");
}